<!DOCTYPE html><html lang="zh-CN" data-theme="light"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"><title>JavaWeb | 无人深空</title><meta name="keywords" content="JavaWeb"><meta name="author" content="zcm"><meta name="copyright" content="zcm"><meta name="format-detection" content="telephone=no"><meta name="theme-color" content="#ffffff"><meta name="description" content="2022版JavaWeb教程（全新技术栈，全程实战）前端三件套 HTML：Hyper Text Markup Language（超文本标记语言）  HTML 是解释型的文本标记语言，不区分大小写  存储页面内容，本身是一种文本文件  常用标签  双标签：有开始标签和结束标签  &lt;html&gt; &lt;&#x2F;html&gt;、&lt;head&gt; &lt;&#x2F;head&gt;、&lt;bod">
<meta property="og:type" content="article">
<meta property="og:title" content="JavaWeb">
<meta property="og:url" content="https://gitee.com/zcmmmm/zcmmmm/2022/09/23/Java-Web/index.html">
<meta property="og:site_name" content="无人深空">
<meta property="og:description" content="2022版JavaWeb教程（全新技术栈，全程实战）前端三件套 HTML：Hyper Text Markup Language（超文本标记语言）  HTML 是解释型的文本标记语言，不区分大小写  存储页面内容，本身是一种文本文件  常用标签  双标签：有开始标签和结束标签  &lt;html&gt; &lt;&#x2F;html&gt;、&lt;head&gt; &lt;&#x2F;head&gt;、&lt;bod">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="https://study-record-images.oss-cn-beijing.aliyuncs.com/Java/JavaWeb/Java%20Web.jpg">
<meta property="article:published_time" content="2022-09-23T02:57:46.000Z">
<meta property="article:modified_time" content="2022-09-23T02:58:51.405Z">
<meta property="article:author" content="zcm">
<meta property="article:tag" content="JavaWeb">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://study-record-images.oss-cn-beijing.aliyuncs.com/Java/JavaWeb/Java%20Web.jpg"><link rel="shortcut icon" href="/img/favicon.png"><link rel="canonical" href="https://gitee.com/zcmmmm/zcmmmm/2022/09/23/Java-Web/"><link rel="preconnect" href="//cdn.jsdelivr.net"/><link rel="preconnect" href="//busuanzi.ibruce.info"/><link rel="stylesheet" href="/css/index.css"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free/css/all.min.css" media="print" onload="this.media='all'"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/node-snackbar/dist/snackbar.min.css" media="print" onload="this.media='all'"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fancyapps/ui/dist/fancybox.min.css" media="print" onload="this.media='all'"><script>const GLOBAL_CONFIG = { 
  root: '/',
  algolia: undefined,
  localSearch: {"path":"/search.xml","preload":false,"languages":{"hits_empty":"找不到您查询的内容：${query}"}},
  translate: undefined,
  noticeOutdate: undefined,
  highlight: {"plugin":"highlighjs","highlightCopy":true,"highlightLang":true,"highlightHeightLimit":200},
  copy: {
    success: '复制成功',
    error: '复制错误',
    noSupport: '浏览器不支持'
  },
  relativeDate: {
    homepage: false,
    post: false
  },
  runtime: '天',
  date_suffix: {
    just: '刚刚',
    min: '分钟前',
    hour: '小时前',
    day: '天前',
    month: '个月前'
  },
  copyright: undefined,
  lightbox: 'fancybox',
  Snackbar: {"chs_to_cht":"你已切换为繁体","cht_to_chs":"你已切换为简体","day_to_night":"你已切换为深色模式","night_to_day":"你已切换为浅色模式","bgLight":"#49b1f5","bgDark":"#1f1f1f","position":"bottom-left"},
  source: {
    justifiedGallery: {
      js: 'https://cdn.jsdelivr.net/npm/flickr-justified-gallery/dist/fjGallery.min.js',
      css: 'https://cdn.jsdelivr.net/npm/flickr-justified-gallery/dist/fjGallery.min.css'
    }
  },
  isPhotoFigcaption: false,
  islazyload: false,
  isAnchor: false
}</script><script id="config-diff">var GLOBAL_CONFIG_SITE = {
  title: 'JavaWeb',
  isPost: true,
  isHome: false,
  isHighlightShrink: false,
  isToc: true,
  postUpdate: '2022-09-23 10:58:51'
}</script><noscript><style type="text/css">
  #nav {
    opacity: 1
  }
  .justified-gallery img {
    opacity: 1
  }

  #recent-posts time,
  #post-meta time {
    display: inline !important
  }
</style></noscript><script>(win=>{
    win.saveToLocal = {
      set: function setWithExpiry(key, value, ttl) {
        if (ttl === 0) return
        const now = new Date()
        const expiryDay = ttl * 86400000
        const item = {
          value: value,
          expiry: now.getTime() + expiryDay,
        }
        localStorage.setItem(key, JSON.stringify(item))
      },

      get: function getWithExpiry(key) {
        const itemStr = localStorage.getItem(key)

        if (!itemStr) {
          return undefined
        }
        const item = JSON.parse(itemStr)
        const now = new Date()

        if (now.getTime() > item.expiry) {
          localStorage.removeItem(key)
          return undefined
        }
        return item.value
      }
    }
  
    win.getScript = url => new Promise((resolve, reject) => {
      const script = document.createElement('script')
      script.src = url
      script.async = true
      script.onerror = reject
      script.onload = script.onreadystatechange = function() {
        const loadState = this.readyState
        if (loadState && loadState !== 'loaded' && loadState !== 'complete') return
        script.onload = script.onreadystatechange = null
        resolve()
      }
      document.head.appendChild(script)
    })
  
      win.activateDarkMode = function () {
        document.documentElement.setAttribute('data-theme', 'dark')
        if (document.querySelector('meta[name="theme-color"]') !== null) {
          document.querySelector('meta[name="theme-color"]').setAttribute('content', '#0d0d0d')
        }
      }
      win.activateLightMode = function () {
        document.documentElement.setAttribute('data-theme', 'light')
        if (document.querySelector('meta[name="theme-color"]') !== null) {
          document.querySelector('meta[name="theme-color"]').setAttribute('content', '#ffffff')
        }
      }
      const t = saveToLocal.get('theme')
    
          if (t === 'dark') activateDarkMode()
          else if (t === 'light') activateLightMode()
        
      const asideStatus = saveToLocal.get('aside-status')
      if (asideStatus !== undefined) {
        if (asideStatus === 'hide') {
          document.documentElement.classList.add('hide-aside')
        } else {
          document.documentElement.classList.remove('hide-aside')
        }
      }
    
    const detectApple = () => {
      if(/iPad|iPhone|iPod|Macintosh/.test(navigator.userAgent)){
        document.documentElement.classList.add('apple')
      }
    }
    detectApple()
    })(window)</script><link rel="stylesheet" href="/css/categories.css?v1"><link rel="stylesheet" href="/css/navigation.css?v1"><link rel="stylesheet" href="/css/custom.css?v1"><meta name="generator" content="Hexo 6.3.0"></head><body><div id="sidebar"><div id="menu-mask"></div><div id="sidebar-menus"><div class="avatar-img is-center"><img src="https://s2.loli.net/2022/09/22/36LN4kcjYOd9HT8.jpg" onerror="onerror=null;src='/img/friend_404.gif'" alt="avatar"/></div><div class="sidebar-site-data site-data is-center"><a href="/archives/"><div class="headline">文章</div><div class="length-num">43</div></a><a href="/tags/"><div class="headline">标签</div><div class="length-num">25</div></a><a href="/categories/"><div class="headline">分类</div><div class="length-num">11</div></a></div><hr/><div class="menus_items"><div class="menus_item"><a class="site-page" href="/"><i class="fa-fw fas fa-home"></i><span> 首页</span></a></div><div class="menus_item"><a class="site-page" href="/archives/"><i class="fa-fw fas fa-archive"></i><span> 时间轴</span></a></div><div class="menus_item"><a class="site-page" href="/tags/"><i class="fa-fw fas fa-tags"></i><span> 标签</span></a></div><div class="menus_item"><a class="site-page" href="/categories/"><i class="fa-fw fas fa-folder-open"></i><span> 分类</span></a></div></div></div></div><div class="post" id="body-wrap"><header class="not-top-img" id="page-header"><nav id="nav"><span id="blog_name"><a id="site-name" href="/">无人深空</a></span><div id="menus"></div><div class="menus_items"><div class="menus_item"><a class="site-page" href="/"><i class="fa-fw fas fa-home"></i><span> 首页</span></a></div><div class="menus_item"><a class="site-page" href="/archives/"><i class="fa-fw fas fa-archive"></i><span> 时间轴</span></a></div><div class="menus_item"><a class="site-page" href="/tags/"><i class="fa-fw fas fa-tags"></i><span> 标签</span></a></div><div class="menus_item"><a class="site-page" href="/categories/"><i class="fa-fw fas fa-folder-open"></i><span> 分类</span></a></div></div><div id="nav-right"><div id="search-button"><a class="site-page social-icon search"><i class="fas fa-search fa-fw"></i></a></div><div id="toggle-menu"><a class="site-page"><i class="fas fa-bars fa-fw"></i></a></div></div></nav></header><main class="layout" id="content-inner"><div id="post"><div id="post-info"><h1 class="post-title">JavaWeb</h1><div id="post-meta"><div class="meta-firstline"><span class="post-meta-date"><i class="far fa-calendar-alt fa-fw post-meta-icon"></i><span class="post-meta-label">发表于</span><time class="post-meta-date-created" datetime="2022-09-23T02:57:46.000Z" title="发表于 2022-09-23 10:57:46">2022-09-23</time><span class="post-meta-separator">|</span><i class="fas fa-history fa-fw post-meta-icon"></i><span class="post-meta-label">更新于</span><time class="post-meta-date-updated" datetime="2022-09-23T02:58:51.405Z" title="更新于 2022-09-23 10:58:51">2022-09-23</time></span><span class="post-meta-categories"><span class="post-meta-separator">|</span><i class="fas fa-inbox fa-fw post-meta-icon"></i><a class="post-meta-categories" href="/categories/Java/">Java</a></span></div><div class="meta-secondline"><span class="post-meta-separator">|</span><span class="post-meta-wordcount"><i class="far fa-file-word fa-fw post-meta-icon"></i><span class="post-meta-label">字数总计:</span><span class="word-count">9.5k</span><span class="post-meta-separator">|</span><i class="far fa-clock fa-fw post-meta-icon"></i><span class="post-meta-label">阅读时长:</span><span>37分钟</span></span><span class="post-meta-separator">|</span><span class="post-meta-pv-cv" id="" data-flag-title="JavaWeb"><i class="far fa-eye fa-fw post-meta-icon"></i><span class="post-meta-label">阅读量:</span><span id="busuanzi_value_page_pv"><i class="fa-solid fa-spinner fa-spin"></i></span></span></div></div></div><article class="post-content" id="article-container"><h3 id="2022版JavaWeb教程（全新技术栈，全程实战）"><a href="#2022版JavaWeb教程（全新技术栈，全程实战）" class="headerlink" title="2022版JavaWeb教程（全新技术栈，全程实战）"></a><a target="_blank" rel="noopener" href="https://www.gulixueyuan.com/my/course/511">2022版JavaWeb教程（全新技术栈，全程实战）</a></h3><h3 id="前端三件套"><a href="#前端三件套" class="headerlink" title="前端三件套"></a>前端三件套</h3><ul>
<li><p>HTML：Hyper Text Markup Language（超文本标记语言）</p>
<ul>
<li><p>HTML 是解释型的文本标记语言，不区分大小写</p>
</li>
<li><p>存储页面内容，本身是一种文本文件</p>
</li>
<li><p>常用标签</p>
<ul>
<li><p>双标签：有开始标签和结束标签</p>
<ul>
<li><p><code>&lt;html&gt; &lt;/html&gt;</code>、<code>&lt;head&gt; &lt;/head&gt;</code>、<code>&lt;body&gt; &lt;/body&gt;</code></p>
</li>
<li><p><code>&lt;hx&gt; &lt;/hx&gt;</code> 标题</p>
</li>
<li><p><code>&lt;ol&gt; &lt;li&gt; &lt;/li&gt; &lt;/ol&gt;</code> 有序列表：<code>start</code> 表示从 * 开始；<code>type</code> 显示类型有 A a I i 1(默认)</p>
</li>
<li><p><code>&lt;ol&gt; &lt;li&gt; &lt;/li&gt; &lt;/ol&gt;</code> 有序列表：<code>type</code> 显示类型有 disc(默认)、circle、square</p>
</li>
<li><p><code>&lt;b&gt; &lt;/b&gt;</code> 加粗</p>
</li>
<li><p><code>&lt;i&gt; &lt;/i&gt;</code> 斜体</p>
</li>
<li><p><code>&lt;u&gt; &lt;/u&gt;</code> 下划线</p>
</li>
<li><p><code>&lt;sub&gt;下标&lt;/sub&gt;</code> <code>&lt;sup&gt;上标&lt;/sup&gt;</code></p>
</li>
<li><p><code>&lt;span&gt; 结合 css 单独给格式 &lt;/span&gt;</code></p>
</li>
<li><p><code>&lt;a href=&quot;超链接的 url&quot;&gt; 超链接 &lt;/a&gt;</code></p>
</li>
</ul>
</li>
<li><p>单标签：开始标签即结束标签</p>
<ul>
<li><p><code>&lt;br/&gt;</code> 表换行</p>
</li>
<li><p><code>&lt;meta charset&gt;</code> 设置字符集</p>
</li>
<li><p><code>&lt;img/&gt;</code> 图片标签：<code>src</code> 指图片路径；<code>width、height</code> 指图片大小；<code>alt</code> 指图片提示</p>
</li>
</ul>
</li>
<li><p>字符实体</p>
<p><img src="https://study-record-images.oss-cn-beijing.aliyuncs.com/Java/JavaWeb/H0W7md.png" alt="H0W7md.png"></p>
</li>
</ul>
</li>
<li><p>demo 演示</p>
</li>
</ul>
<figure class="highlight html"><table><tr><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">html</span>&gt;</span></span><br><span class="line">	<span class="tag">&lt;<span class="name">head</span>&gt;</span></span><br><span class="line">		<span class="tag">&lt;<span class="name">title</span>&gt;</span>这是我的第一个网页<span class="tag">&lt;/<span class="name">title</span>&gt;</span></span><br><span class="line">		<span class="tag">&lt;<span class="name">meta</span> <span class="attr">charset</span>=<span class="string">&quot;UTF-8&quot;</span>&gt;</span></span><br><span class="line">	<span class="tag">&lt;/<span class="name">head</span>&gt;</span></span><br><span class="line">	<span class="tag">&lt;<span class="name">body</span>&gt;</span></span><br><span class="line"></span><br><span class="line">		HELLO WORLD!<span class="tag">&lt;<span class="name">br</span>/&gt;</span>你好，HTML！</span><br><span class="line">		<span class="tag">&lt;<span class="name">p</span>&gt;</span>这里是一个段落<span class="tag">&lt;/<span class="name">p</span>&gt;</span></span><br><span class="line">		<span class="tag">&lt;<span class="name">p</span>&gt;</span>这里是第二个段落<span class="tag">&lt;/<span class="name">p</span>&gt;</span></span><br><span class="line">		<span class="tag">&lt;<span class="name">img</span> <span class="attr">src</span>=<span class="string">&quot;图片路径&quot;</span> <span class="attr">width</span>=<span class="string">&quot;57&quot;</span> <span class="attr">height</span>=<span class="string">&quot;73&quot;</span> <span class="attr">alt</span>=<span class="string">&quot;这里是一张图片&quot;</span>/&gt;</span></span><br><span class="line">		<span class="tag">&lt;<span class="name">h1</span>&gt;</span>标题一<span class="tag">&lt;/<span class="name">h1</span>&gt;</span></span><br><span class="line">		<span class="tag">&lt;<span class="name">h2</span>&gt;</span>标题一<span class="tag">&lt;/<span class="name">h2</span>&gt;</span></span><br><span class="line">		<span class="tag">&lt;<span class="name">h3</span>&gt;</span>标题一<span class="tag">&lt;/<span class="name">h3</span>&gt;</span></span><br><span class="line">		<span class="tag">&lt;<span class="name">h4</span>&gt;</span>标题一<span class="tag">&lt;/<span class="name">h4</span>&gt;</span></span><br><span class="line">		<span class="tag">&lt;<span class="name">h5</span>&gt;</span>标题一<span class="tag">&lt;/<span class="name">h5</span>&gt;</span></span><br><span class="line">		<span class="tag">&lt;<span class="name">h6</span>&gt;</span>标题一<span class="tag">&lt;/<span class="name">h6</span>&gt;</span></span><br><span class="line"></span><br><span class="line">		武林高手排行榜:</span><br><span class="line">		<span class="tag">&lt;<span class="name">ol</span> <span class="attr">type</span>=<span class="string">&quot;i&quot;</span> <span class="attr">start</span>=<span class="string">&quot;3&quot;</span>&gt;</span></span><br><span class="line">			<span class="tag">&lt;<span class="name">li</span>&gt;</span>扫地僧<span class="tag">&lt;/<span class="name">li</span>&gt;</span></span><br><span class="line">			<span class="tag">&lt;<span class="name">li</span>&gt;</span>萧远山<span class="tag">&lt;/<span class="name">li</span>&gt;</span></span><br><span class="line">			<span class="tag">&lt;<span class="name">li</span>&gt;</span>慕容博<span class="tag">&lt;/<span class="name">li</span>&gt;</span></span><br><span class="line">			<span class="tag">&lt;<span class="name">li</span>&gt;</span>虚竹<span class="tag">&lt;/<span class="name">li</span>&gt;</span></span><br><span class="line">			<span class="tag">&lt;<span class="name">li</span>&gt;</span>阿紫<span class="tag">&lt;/<span class="name">li</span>&gt;</span></span><br><span class="line">		<span class="tag">&lt;/<span class="name">ol</span>&gt;</span></span><br><span class="line">		武林大会人员名单：</span><br><span class="line">		<span class="tag">&lt;<span class="name">ul</span> <span class="attr">type</span>=<span class="string">&quot;circle&quot;</span>&gt;</span></span><br><span class="line">			<span class="tag">&lt;<span class="name">li</span>&gt;</span>乔峰<span class="tag">&lt;/<span class="name">li</span>&gt;</span></span><br><span class="line">			<span class="tag">&lt;<span class="name">li</span>&gt;</span>阿朱<span class="tag">&lt;/<span class="name">li</span>&gt;</span></span><br><span class="line">			<span class="tag">&lt;<span class="name">li</span>&gt;</span>马夫人<span class="tag">&lt;/<span class="name">li</span>&gt;</span></span><br><span class="line">			<span class="tag">&lt;<span class="name">li</span>&gt;</span>白世镜<span class="tag">&lt;/<span class="name">li</span>&gt;</span></span><br><span class="line">		<span class="tag">&lt;/<span class="name">ul</span>&gt;</span></span><br><span class="line"></span><br><span class="line">		你是<span class="tag">&lt;<span class="name">b</span>&gt;</span><span class="tag">&lt;<span class="name">i</span>&gt;</span><span class="tag">&lt;<span class="name">u</span>&gt;</span>喜欢<span class="tag">&lt;/<span class="name">u</span>&gt;</span><span class="tag">&lt;/<span class="name">i</span>&gt;</span><span class="tag">&lt;/<span class="name">b</span>&gt;</span>是<span class="tag">&lt;<span class="name">b</span>&gt;</span>甜<span class="tag">&lt;/<span class="name">b</span>&gt;</span>月饼还是<span class="tag">&lt;<span class="name">i</span>&gt;</span>咸<span class="tag">&lt;/<span class="name">i</span>&gt;</span><span class="tag">&lt;<span class="name">u</span>&gt;</span>月饼<span class="tag">&lt;/<span class="name">u</span>&gt;</span>？</span><br><span class="line">		<span class="tag">&lt;<span class="name">br</span>/&gt;</span></span><br><span class="line"></span><br><span class="line">		水分子的化学式： H<span class="tag">&lt;<span class="name">sub</span>&gt;</span>2<span class="tag">&lt;/<span class="name">sub</span>&gt;</span>O <span class="tag">&lt;<span class="name">br</span>/&gt;</span></span><br><span class="line">		氧气的化学式： O<span class="tag">&lt;<span class="name">sup</span>&gt;</span>2<span class="tag">&lt;/<span class="name">sup</span>&gt;</span><span class="tag">&lt;<span class="name">br</span>/&gt;</span></span><br><span class="line"></span><br><span class="line">		5<span class="symbol">&amp;lt;</span>10</span><br><span class="line">		10<span class="symbol">&amp;gt;</span>5</span><br><span class="line">		5<span class="symbol">&amp;le;</span>10</span><br><span class="line">		10<span class="symbol">&amp;ge;</span>5</span><br><span class="line">		注册商标 <span class="symbol">&amp;reg;</span></span><br><span class="line">		版权符号 <span class="symbol">&amp;copy;</span></span><br><span class="line"></span><br><span class="line">		<span class="tag">&lt;<span class="name">span</span>&gt;</span>赵又廷<span class="tag">&lt;/<span class="name">span</span>&gt;</span>，夺妻之仇。</span><br><span class="line"></span><br><span class="line">		<span class="tag">&lt;<span class="name">a</span> <span class="attr">href</span>=<span class="string">&quot;http://www.baidu.com&quot;</span> <span class="attr">target</span>=<span class="string">&quot;_self&quot;</span>&gt;</span>百度一下<span class="tag">&lt;/<span class="name">a</span>&gt;</span></span><br><span class="line">	<span class="tag">&lt;/<span class="name">body</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">html</span>&gt;</span></span><br></pre></td></tr></table></figure>

<figure class="highlight html"><table><tr><td class="code"><pre><span class="line"><span class="comment">&lt;!--</span></span><br><span class="line"><span class="comment">    表格	table</span></span><br><span class="line"><span class="comment">	行	 tr</span></span><br><span class="line"><span class="comment">	列	 td</span></span><br><span class="line"><span class="comment">	表头列	th</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">	table 中有如下属性（虽然已经淘汰，但是最好了解一下）</span></span><br><span class="line"><span class="comment">	- border: 表格边框的粗细</span></span><br><span class="line"><span class="comment">	- width: 表格的宽度</span></span><br><span class="line"><span class="comment">	- cellspacing: 单元格间距</span></span><br><span class="line"><span class="comment">	- cellpadding: 单元格填充</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">	tr中有一个属性： align -&gt; center , left , right </span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">	rowspan : 行合并</span></span><br><span class="line"><span class="comment">	colspan : 列合并</span></span><br><span class="line"><span class="comment">--&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="tag">&lt;<span class="name">html</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">head</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">title</span>&gt;</span>表格标签的学习<span class="tag">&lt;/<span class="name">title</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">meta</span> <span class="attr">charset</span>=<span class="string">&quot;UTF-8&quot;</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">head</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">body</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">table</span> <span class="attr">border</span>=<span class="string">&quot;1&quot;</span> <span class="attr">width</span>=<span class="string">&quot;600&quot;</span> <span class="attr">cellspacing</span>=<span class="string">&quot;0&quot;</span> <span class="attr">cellpadding</span>=<span class="string">&quot;4&quot;</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">tr</span> <span class="attr">align</span>=<span class="string">&quot;center&quot;</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">th</span>&gt;</span>姓名<span class="tag">&lt;/<span class="name">th</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">th</span>&gt;</span>门派<span class="tag">&lt;/<span class="name">th</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">th</span>&gt;</span>成名绝技<span class="tag">&lt;/<span class="name">th</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">th</span>&gt;</span>内功值<span class="tag">&lt;/<span class="name">th</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">tr</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">tr</span> <span class="attr">align</span>=<span class="string">&quot;center&quot;</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">td</span>&gt;</span>乔峰<span class="tag">&lt;/<span class="name">td</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">td</span>&gt;</span>丐帮<span class="tag">&lt;/<span class="name">td</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">td</span>&gt;</span>少林长拳<span class="tag">&lt;/<span class="name">td</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">td</span>&gt;</span>5000<span class="tag">&lt;/<span class="name">td</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">tr</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">tr</span> <span class="attr">align</span>=<span class="string">&quot;center&quot;</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">td</span>&gt;</span>虚竹<span class="tag">&lt;/<span class="name">td</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">td</span>&gt;</span>灵鹫宫<span class="tag">&lt;/<span class="name">td</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">td</span>&gt;</span>北冥神功<span class="tag">&lt;/<span class="name">td</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">td</span>&gt;</span>15000<span class="tag">&lt;/<span class="name">td</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">tr</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">tr</span> <span class="attr">align</span>=<span class="string">&quot;center&quot;</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">td</span>&gt;</span>扫地僧<span class="tag">&lt;/<span class="name">td</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">td</span>&gt;</span>少林寺<span class="tag">&lt;/<span class="name">td</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">td</span>&gt;</span>七十二绝技<span class="tag">&lt;/<span class="name">td</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">td</span>&gt;</span>未知<span class="tag">&lt;/<span class="name">td</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">tr</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">table</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">hr</span>/&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">table</span> <span class="attr">border</span>=<span class="string">&quot;1&quot;</span> <span class="attr">cellspacing</span>=<span class="string">&quot;0&quot;</span> <span class="attr">cellpadding</span>=<span class="string">&quot;4&quot;</span> <span class="attr">width</span>=<span class="string">&quot;600&quot;</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">tr</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">th</span>&gt;</span>名称<span class="tag">&lt;/<span class="name">th</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">th</span>&gt;</span>单价<span class="tag">&lt;/<span class="name">th</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">th</span>&gt;</span>数量<span class="tag">&lt;/<span class="name">th</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">th</span>&gt;</span>小计<span class="tag">&lt;/<span class="name">th</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">tr</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">tr</span> <span class="attr">align</span>=<span class="string">&quot;center&quot;</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">td</span>&gt;</span>苹果<span class="tag">&lt;/<span class="name">td</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">td</span> <span class="attr">rowspan</span>=<span class="string">&quot;2&quot;</span>&gt;</span>5<span class="tag">&lt;/<span class="name">td</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">td</span>&gt;</span>20<span class="tag">&lt;/<span class="name">td</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">td</span>&gt;</span>100<span class="tag">&lt;/<span class="name">td</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">tr</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">tr</span> <span class="attr">align</span>=<span class="string">&quot;center&quot;</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">td</span>&gt;</span>菠萝<span class="tag">&lt;/<span class="name">td</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">td</span>&gt;</span>15<span class="tag">&lt;/<span class="name">td</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">td</span>&gt;</span>45<span class="tag">&lt;/<span class="name">td</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">tr</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">tr</span> <span class="attr">align</span>=<span class="string">&quot;center&quot;</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">td</span>&gt;</span>总计<span class="tag">&lt;/<span class="name">td</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">td</span> <span class="attr">colspan</span>=<span class="string">&quot;4&quot;</span>&gt;</span>145<span class="tag">&lt;/<span class="name">td</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">tr</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">table</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">body</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">html</span>&gt;</span></span><br></pre></td></tr></table></figure>

<figure class="highlight html"><table><tr><td class="code"><pre><span class="line"><span class="comment">&lt;!--</span></span><br><span class="line"><span class="comment">	form 表单</span></span><br><span class="line"><span class="comment">	action 表接收返回信息的组件</span></span><br><span class="line"><span class="comment">	method 传输方式</span></span><br><span class="line"><span class="comment">	</span></span><br><span class="line"><span class="comment">	input type=&quot;text&quot; 		文本框，其中 name 属性必须要指定，否则这个文本框的数据将来是不会发送给服务器的</span></span><br><span class="line"><span class="comment">	input type=&quot;password&quot; 	密码框，不明文显示</span></span><br><span class="line"><span class="comment">	input type=&quot;radio&quot; 		单选按钮。name 属性值需保持一致才可以实现单选，可以通过 checked 属性设置默认选中的项</span></span><br><span class="line"><span class="comment">	input type=&quot;checkbox&quot; 	复选框。name 属性值建议保持一致，以便服务器端获取值的时候获取的是一个数组</span></span><br><span class="line"><span class="comment">	select 					下拉列表。每一个选项是 option，其中 value 属性是发送给服务器的值，selected 表示默认选中的项</span></span><br><span class="line"><span class="comment">	textarea 				多行文本框（即文本域），value 值就是开始结束标签之间的内容</span></span><br><span class="line"><span class="comment">	input type=&quot;submit&quot; 	提交按钮</span></span><br><span class="line"><span class="comment">	input type=&quot;reset&quot; 		重置按钮，恢复默认状态</span></span><br><span class="line"><span class="comment">	input type=&quot;button&quot; 	普通按钮</span></span><br><span class="line"><span class="comment">--&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="tag">&lt;<span class="name">html</span>&gt;</span></span><br><span class="line">	<span class="tag">&lt;<span class="name">head</span>&gt;</span></span><br><span class="line">		<span class="tag">&lt;<span class="name">title</span>&gt;</span>表单标签的学习<span class="tag">&lt;/<span class="name">title</span>&gt;</span></span><br><span class="line">		<span class="tag">&lt;<span class="name">meta</span> <span class="attr">charset</span>=<span class="string">&quot;UTF-8&quot;</span>&gt;</span></span><br><span class="line">		</span><br><span class="line">	<span class="tag">&lt;/<span class="name">head</span>&gt;</span></span><br><span class="line">	<span class="tag">&lt;<span class="name">body</span>&gt;</span></span><br><span class="line">		<span class="tag">&lt;<span class="name">form</span> <span class="attr">action</span>=<span class="string">&quot;接收信息的组件&quot;</span> <span class="attr">method</span>=<span class="string">&quot;post&quot;</span>&gt;</span></span><br><span class="line">			昵称：<span class="tag">&lt;<span class="name">input</span> <span class="attr">type</span>=<span class="string">&quot;text&quot;</span> <span class="attr">value</span>=<span class="string">&quot;请输入你的昵称&quot;</span>/&gt;</span><span class="tag">&lt;<span class="name">br</span>/&gt;</span></span><br><span class="line">			密码：<span class="tag">&lt;<span class="name">input</span> <span class="attr">type</span>=<span class="string">&quot;password&quot;</span> <span class="attr">name</span>=<span class="string">&quot;pwd&quot;</span>/&gt;</span><span class="tag">&lt;<span class="name">br</span>/&gt;</span></span><br><span class="line">			性别：<span class="tag">&lt;<span class="name">input</span> <span class="attr">type</span>=<span class="string">&quot;radio&quot;</span> <span class="attr">name</span>=<span class="string">&quot;gender&quot;</span> <span class="attr">value</span>=<span class="string">&quot;male&quot;</span>/&gt;</span>男</span><br><span class="line">	  			  <span class="tag">&lt;<span class="name">input</span> <span class="attr">type</span>=<span class="string">&quot;radio&quot;</span> <span class="attr">name</span>=<span class="string">&quot;gender&quot;</span> <span class="attr">value</span>=<span class="string">&quot;female&quot;</span> <span class="attr">checked</span>/&gt;</span>女<span class="tag">&lt;<span class="name">br</span>/&gt;</span></span><br><span class="line">			爱好：<span class="tag">&lt;<span class="name">input</span> <span class="attr">type</span>=<span class="string">&quot;checkbox&quot;</span> <span class="attr">name</span>=<span class="string">&quot;hobby&quot;</span> <span class="attr">value</span>=<span class="string">&quot;basketball&quot;</span>/&gt;</span>篮球</span><br><span class="line">				  <span class="tag">&lt;<span class="name">input</span> <span class="attr">type</span>=<span class="string">&quot;checkbox&quot;</span> <span class="attr">name</span>=<span class="string">&quot;hobby&quot;</span> <span class="attr">value</span>=<span class="string">&quot;football&quot;</span> <span class="attr">checked</span>/&gt;</span>足球</span><br><span class="line">				  <span class="tag">&lt;<span class="name">input</span> <span class="attr">type</span>=<span class="string">&quot;checkbox&quot;</span> <span class="attr">name</span>=<span class="string">&quot;hobby&quot;</span> <span class="attr">value</span>=<span class="string">&quot;earth&quot;</span> <span class="attr">checked</span>/&gt;</span>地球<span class="tag">&lt;<span class="name">br</span>/&gt;</span></span><br><span class="line">			星座：<span class="tag">&lt;<span class="name">select</span> <span class="attr">name</span>=<span class="string">&quot;star&quot;</span>&gt;</span></span><br><span class="line">					<span class="tag">&lt;<span class="name">option</span> <span class="attr">value</span>=<span class="string">&quot;1&quot;</span>&gt;</span>白羊座<span class="tag">&lt;/<span class="name">option</span>&gt;</span></span><br><span class="line">					<span class="tag">&lt;<span class="name">option</span> <span class="attr">value</span>=<span class="string">&quot;2&quot;</span> <span class="attr">selected</span>&gt;</span>金牛座<span class="tag">&lt;/<span class="name">option</span>&gt;</span></span><br><span class="line">					<span class="tag">&lt;<span class="name">option</span> <span class="attr">value</span>=<span class="string">&quot;3&quot;</span>&gt;</span>双子座<span class="tag">&lt;/<span class="name">option</span>&gt;</span></span><br><span class="line">				  <span class="tag">&lt;/<span class="name">select</span>&gt;</span><span class="tag">&lt;<span class="name">br</span>/&gt;</span></span><br><span class="line">			备注：<span class="tag">&lt;<span class="name">textarea</span> <span class="attr">name</span>=<span class="string">&quot;remark&quot;</span> <span class="attr">rows</span>=<span class="string">&quot;4&quot;</span> <span class="attr">cols</span>=<span class="string">&quot;50&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">textarea</span>&gt;</span><span class="tag">&lt;<span class="name">br</span>/&gt;</span></span><br><span class="line">			<span class="tag">&lt;<span class="name">input</span> <span class="attr">type</span>=<span class="string">&quot;submit&quot;</span> <span class="attr">value</span>=<span class="string">&quot; 注册 &quot;</span>/&gt;</span></span><br><span class="line">			<span class="tag">&lt;<span class="name">input</span> <span class="attr">type</span>=<span class="string">&quot;reset&quot;</span> <span class="attr">value</span>=<span class="string">&quot;重置&quot;</span>/&gt;</span></span><br><span class="line">			<span class="tag">&lt;<span class="name">input</span> <span class="attr">type</span>=<span class="string">&quot;button&quot;</span> <span class="attr">value</span>=<span class="string">&quot;普通按钮&quot;</span>/&gt;</span></span><br><span class="line">		<span class="tag">&lt;/<span class="name">form</span>&gt;</span></span><br><span class="line">	<span class="tag">&lt;/<span class="name">body</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">html</span>&gt;</span></span><br><span class="line"></span><br></pre></td></tr></table></figure>

<figure class="highlight html"><table><tr><td class="code"><pre><span class="line"><span class="comment">&lt;!--</span></span><br><span class="line"><span class="comment">	frameset 	页面框架，这个标签已经淘汰，了解即可</span></span><br><span class="line"><span class="comment">	frame		框架中的具体页面引用</span></span><br><span class="line"><span class="comment">--&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">html</span>&gt;</span></span><br><span class="line">	<span class="tag">&lt;<span class="name">head</span>&gt;</span><span class="tag">&lt;/<span class="name">head</span>&gt;</span></span><br><span class="line">	<span class="tag">&lt;<span class="name">frameset</span> <span class="attr">rows</span>=<span class="string">&quot;20%,*&quot;</span> &gt;</span>			<span class="comment">&lt;!-- 分为上20%，下剩余部分 两部分--&gt;</span></span><br><span class="line">		<span class="tag">&lt;<span class="name">frame</span> <span class="attr">src</span>=<span class="string">&quot;top.html&quot;</span>/&gt;</span></span><br><span class="line">		<span class="tag">&lt;<span class="name">frameset</span> <span class="attr">cols</span>=<span class="string">&quot;15%,*&quot;</span>&gt;</span>			<span class="comment">&lt;!-- 分为左15%，右剩余部分 两部分--&gt;</span></span><br><span class="line">			<span class="tag">&lt;<span class="name">frame</span> <span class="attr">src</span>=<span class="string">&quot;left.html&quot;</span>/&gt;</span></span><br><span class="line">			<span class="tag">&lt;<span class="name">frameset</span> <span class="attr">rows</span>=<span class="string">&quot;80%,*&quot;</span>&gt;</span> 	<span class="comment">&lt;!-- 分为上80%，下剩余部分 两部分--&gt;</span></span><br><span class="line">				<span class="tag">&lt;<span class="name">frame</span> <span class="attr">src</span>=<span class="string">&quot;main.html&quot;</span>/&gt;</span></span><br><span class="line">				<span class="tag">&lt;<span class="name">frame</span> <span class="attr">src</span>=<span class="string">&quot;bottom.html&quot;</span>/&gt;</span></span><br><span class="line">			<span class="tag">&lt;/<span class="name">frameset</span>&gt;</span></span><br><span class="line">		<span class="tag">&lt;/<span class="name">frameset</span>&gt;</span></span><br><span class="line">	<span class="tag">&lt;/<span class="name">frameset</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">html</span>&gt;</span></span><br><span class="line"></span><br><span class="line">---------------------------------------------------------------------------</span><br><span class="line"></span><br><span class="line"><span class="comment">&lt;!--</span></span><br><span class="line"><span class="comment">	iframe		页面中嵌入页面</span></span><br><span class="line"><span class="comment">--&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">html</span>&gt;</span></span><br><span class="line">	<span class="tag">&lt;<span class="name">head</span>&gt;</span></span><br><span class="line">		<span class="tag">&lt;<span class="name">meta</span> <span class="attr">charset</span>=<span class="string">&quot;utf-8&quot;</span>&gt;</span></span><br><span class="line">	<span class="tag">&lt;/<span class="name">head</span>&gt;</span></span><br><span class="line">	<span class="tag">&lt;<span class="name">body</span>&gt;</span></span><br><span class="line">		下面在该页中嵌入 `top.html` 页面</span><br><span class="line">		<span class="tag">&lt;<span class="name">iframe</span> <span class="attr">src</span>=<span class="string">&quot;top.html&quot;</span>/&gt;</span></span><br><span class="line">	<span class="tag">&lt;/<span class="name">body</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">html</span>&gt;</span></span><br></pre></td></tr></table></figure>
</li>
<li><p>CSS</p>
<ul>
<li><p>网页样式，定义内容显示风格</p>
</li>
<li><p>HTML 引入 CSS 文件，在 head 中加入 <code>&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;css文件路径&quot;&gt;</code></p>
</li>
<li><p>CSS 最基本分类</p>
<ul>
<li>标签样式表</li>
<li>类样式表</li>
<li>ID 样式表</li>
</ul>
</li>
<li><p>CSS 位置分类（就近原则）</p>
<ul>
<li>嵌入式样式表</li>
<li>内部样式表</li>
<li>外部样式表（推荐）</li>
</ul>
</li>
<li><p>CSS 盒子模型</p>
<ul>
<li>border：边框</li>
<li>margin：间隔</li>
<li>padding：填充</li>
</ul>
<p><a target="_blank" rel="noopener" href="https://imgtu.com/i/HBpzmd"><img src="https://study-record-images.oss-cn-beijing.aliyuncs.com/Java/JavaWeb/HBpzmd.png" alt="HBpzmd.png"></a></p>
</li>
<li><p><a target="_blank" rel="noopener" href="https://www.runoob.com/css/css-positioning.html">CSS 布局</a></p>
<ul>
<li>absolute 绝对布局：绝对定位的元素的位置相对于最近的已定位父元素，如果元素没有已定位的父元素，那么它的位置相对于<html></li>
<li>relative 相对布局：相对定位元素的定位是相对其正常位置</li>
</ul>
</li>
</ul>
</li>
<li><p><a target="_blank" rel="noopener" href="https://www.w3school.com.cn/js/index.asp">Javascript</a></p>
<ul>
<li>JS 是客户端（浏览器端）运行的脚本语言，语法风格与 Java 类型</li>
<li>JS 是弱类型语言</li>
<li>HTML 引入 JS，在 head 中加入 <code>&lt;script type=&quot;text/javascript&quot; src=&quot;js文件路径&quot;&gt;&lt;/script&gt;</code></li>
<li><a target="_blank" rel="noopener" href="https://www.w3school.com.cn/js/js_htmldom.asp">DOM 操作</a></li>
</ul>
</li>
<li><p><strong>BS 和 CS 对比</strong></p>
<ul>
<li><p><strong>CS：客户端服务器架构模式</strong></p>
<p>优点：充分利用客户端机器的资源，减轻服务器的负荷（一部分安全要求不高的计算任务存储任务放在客户端执行，不需要把所有的计算和存储都在服务器端执行，从而能够减轻服务器的压力，也能够减轻网络负荷）</p>
<p>缺点：需要安装；升级维护成本较高</p>
</li>
<li><p><strong>BS：浏览器服务器架构模式</strong></p>
<p>优点：客户端不需要安装；维护成本较低</p>
<p>缺点：所有的计算和存储任务都是放在服务器端的，服务器的负荷较重；在服务端计算完成之后把结果再传输给客户端，因此客户端和服务器端会进行非常频繁的数据通信，从而网络负荷较重</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">create table t_fruit (</span><br><span class="line">	fid int primary key auto_increment,</span><br><span class="line">    fnamr varchar(32) not null default &#x27;&#x27;,</span><br><span class="line">    price double not null default 0,</span><br><span class="line">    fcount int not null default 0,</span><br><span class="line">    remark varchar(255) not null default &#x27;&#x27;</span><br><span class="line">)</span><br></pre></td></tr></table></figure></li>
</ul>
</li>
</ul>
<h3 id="JavaWeb-fruit-项目"><a href="#JavaWeb-fruit-项目" class="headerlink" title="JavaWeb fruit 项目"></a>JavaWeb fruit 项目</h3><ul>
<li><p><a target="_blank" rel="noopener" href="https://www.gulixueyuan.com/course/511/task/22421/show">Tomcat 部署项目</a></p>
<ul>
<li><p>Post 方式设置编码，防止中文乱码（get 方式不用设置）</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">// 必须放在获取任意参数前，否则失效</span></span><br><span class="line">req.setCharacterEncoding(<span class="string">&quot;UTF-8&quot;</span>);</span><br></pre></td></tr></table></figure></li>
</ul>
</li>
<li><p>Servlet</p>
<ul>
<li><p>Servlet 继承关系</p>
<p><a target="_blank" rel="noopener" href="https://imgtu.com/i/HWFiM4"><img src="https://study-record-images.oss-cn-beijing.aliyuncs.com/Java/JavaWeb/HWFiM4.png" alt="HWFiM4.png" style="zoom:80%;" /></a></p>
</li>
<li><p>Servlet API</p>
<p>有请求时 service 方法会自动响应（底层是 tomcat 容器调用）</p>
<p>在 HttpService 中分析请求方式，如 get、post、head、delete 等等</p>
<p>之后再决定调用对应方法：<code>do+请求方式</code></p>
 <img src="https://study-record-images.oss-cn-beijing.aliyuncs.com/Java/JavaWeb/HWFFsJ.png" alt="HWFFsJ.png" style="zoom:50%;" />
</li>
<li><p>Servlet 生命周期</p>
<ul>
<li><p>init() —-&gt; service() —-&gt; destory()</p>
</li>
<li><p>Servlet 生命周期由 tomcat 管理</p>
<ul>
<li>第一次接收请求时，Servlet 会进行实例化（调用构造方法）、初始化（init）、服务（service）</li>
<li>第二次请求开始，每一次都是服务（service）</li>
<li>容器关闭时，实例被销毁（destory）</li>
</ul>
</li>
<li><p>tomcat 只会创建一个 Servlet 实例，所有请求都是该实例去响应</p>
<ul>
<li>优点：提高系统响应速度</li>
<li>缺点：第一次请求时耗时长</li>
</ul>
</li>
<li><p>如需提高响应速度，则需设置 servlet 初始化时机（默认是再第一次接收请求时实例化、初始化）</p>
<ul>
<li><p>在 <code>web.xml</code> 中设置 <code>&lt;load-on-startup&gt;1&lt;/load-on-startup&gt;</code></p>
<p>数字越小时间越靠前，一般为正整数</p>
<figure class="highlight xml"><table><tr><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">servlet</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">load-on-startup</span>&gt;</span>1<span class="tag">&lt;/<span class="name">load-on-startup</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">servlet</span>&gt;</span></span><br></pre></td></tr></table></figure></li>
</ul>
</li>
<li><p>Servlet 在容器中是</p>
<ul>
<li>单例的：只有一个实例化对象，该对象处理所有请求</li>
<li>线程不安全的：尽量不在 Servlet 中定义成员变量</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><p><a target="_blank" rel="noopener" href="https://www.cnblogs.com/ranyonsue/p/5984001.html">HTTP 协议</a></p>
<ul>
<li><p>HTTP 为超文本传输协议</p>
</li>
<li><p>HTTP 是无状态的：服务器无法区分两个请求是否来自同一个客户端</p>
<ul>
<li>通过<code>会话跟踪技术</code>解决无状态问题（详见下）</li>
</ul>
</li>
<li><p>HTTP 请求</p>
<ul>
<li>请求行：包含请求方式、请求的 URL、请求的协议（一般为 HTTP 1.1）</li>
<li>请求消息头：包含很多客户端要告诉服务器的消息（如浏览器版本、型号等）</li>
<li>请求体：<ul>
<li>get 方式：没有请求体，但有个 <code>queryString</code></li>
<li>post 方式：有请求体， form data</li>
<li>json 格式：有请求体， request payload</li>
</ul>
</li>
</ul>
</li>
<li><p>HTTP 响应</p>
<ul>
<li>响应行：包含协议、响应状态码（成功为2xx）、响应状态</li>
<li>响应头：包含服务器的信息、服务器发送给浏览器的信息（内容的媒体类型、编码、内容长度等）</li>
<li>响应体：响应的实际内容（如请求 <code>add.html</code> 时，响应内容为 html 文件内容）</li>
</ul>
</li>
<li><p>会话 session</p>
<ul>
<li><p>会话跟踪技术</p>
<ul>
<li><p>客户端第一次请求时，服务器给其分配一个 sessionID</p>
</li>
<li><p>第二次请求开始会把 sessionID 一起带着给服务器，服务器根据 sessionID 判断客户端身份</p>
</li>
<li><p>常用 API</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">request.getSession(): 获取当前会话 session，没有则创建一个新的并分配 sessionID</span><br><span class="line">request.getSession(<span class="literal">true</span>): 效果同上</span><br><span class="line">request.getSession(<span class="literal">false</span>): 获取当前会话，如无则返回 <span class="literal">null</span>，不会创建新的</span><br><span class="line">    </span><br><span class="line">session.getId(): 获取 sessionID</span><br><span class="line">session.isNew(): 判断该 session 是不是新的</span><br><span class="line">session.getMaxInactiveInterval(): session 的非激活间隔时长，默认 <span class="number">1800</span> 秒</span><br><span class="line">session.setMaxInactiveInterval(): 设置 session 的非激活间隔时长</span><br><span class="line">session.invalidate(): 强制使当前会话立即失效</span><br></pre></td></tr></table></figure></li>
</ul>
</li>
<li><p>session 保存作用域</p>
<ul>
<li><p>session 保存作用域是和具体某个 session 绑定的（session 不用访问其他 session 的保存作用域）</p>
</li>
<li><p>常用的API：</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="type">HttpSession</span> <span class="variable">session</span> <span class="operator">=</span> request.getSession();</span><br><span class="line">session.setAttribute(<span class="string">&quot;uname&quot;</span>, <span class="string">&quot;try&quot;</span>);	<span class="comment">// 向当前 session 保存作用域保存一个数据</span></span><br><span class="line">session.getAttribute(<span class="string">&quot;uname&quot;</span>);			<span class="comment">// 根据 key 获取保存作用域的值</span></span><br><span class="line">session.removeAttribute(<span class="string">&quot;uname&quot;</span>);		<span class="comment">// 根据 key 删除 k-v</span></span><br></pre></td></tr></table></figure></li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><p>服务器内部转发以及客户端重定向</p>
<ul>
<li>服务器内部转发：<code>request.getRequestDispatcher(&quot;...&quot;).forward(request, response)</code><ul>
<li>一次请求响应的过程</li>
<li>对于客户端而言，内部经过了多少次转发，客户端是不知道的</li>
<li>地址栏没有变化</li>
</ul>
</li>
<li>客户端重定向：<code>response.sendRedirect(&quot;....&quot;)</code><ul>
<li>两次请求响应的过程</li>
<li>客户端知道请求 URL 有变化</li>
<li>地址栏有变化</li>
</ul>
</li>
</ul>
</li>
<li><p><strong>Thymeleaf - 视图模板技术（课时30-39）</strong></p>
<ul>
<li>进行视图渲染</li>
</ul>
<ol>
<li><p>添加 <code>thymeleaf</code> 的 jar 包（6个）</p>
</li>
<li><p>新建一个 Servlet 类 ViewBaseServlet</p>
</li>
<li><p>在 <code>web.xml</code> 文件中添加配置</p>
<ul>
<li>配置前缀 view-prefix</li>
<li>配置后缀 view-suffix</li>
</ul>
</li>
<li><p>使得我们的 Servlet 继承 ViewBaseServlet</p>
</li>
<li><p>根据逻辑视图名称 得到 物理视图名称</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">// 此处的视图名称是 index</span></span><br><span class="line"><span class="comment">// 那么thymeleaf会将这个 逻辑视图名称 对应到 物理视图 名称上去</span></span><br><span class="line"><span class="comment">// 逻辑视图名称 ：   index</span></span><br><span class="line"><span class="comment">// 物理视图名称 ：   view-prefix + 逻辑视图名称 + view-suffix</span></span><br><span class="line"><span class="comment">// 所以真实的视图名称是：      /index.html</span></span><br><span class="line"><span class="built_in">super</span>.processTemplate(<span class="string">&quot;index&quot;</span>,request,response);</span><br></pre></td></tr></table></figure>
</li>
<li><p>使用 <code>thymeleaf</code> 的标签</p>
<p><code>th:if、th:unless、th:each、th:text</code></p>
</li>
</ol>
</li>
<li><p>保存作用域（原始情况下认为有如下四种）</p>
<ul>
<li>page：页面级别，现在基本不用</li>
<li>request：一次请求响应范围</li>
<li>session：一次会话范围有效</li>
<li>application：一次应用程序范围有效</li>
</ul>
</li>
<li><p>路径问题</p>
<ul>
<li>相对路径</li>
<li>绝对路径</li>
</ul>
</li>
<li><p><strong>MVC 模式（课时40-45）</strong></p>
<ul>
<li><p>以前版本存在问题</p>
<ul>
<li><p>一个请求对应一个 <code>Servlet</code>，导致 <code>Servlet</code> 过多</p>
</li>
<li><p>解决方法：把一些列的请求合并称一个 <code>Servlet</code>，通过一个operate的值来决定调用 <code>FruitServlet</code> 中的哪一个方法（使用 <code>switch-case</code>）</p>
<p>存在问题： <code>switch-case</code> 过长</p>
</li>
<li><p>解决方法：在 <code>Servlet</code> 中使用反射技术，规定 <code>operate</code> 的值和方法名一致，根据接收到operate的值调用对应的方法进行响应，如果找不到对应的方法，则抛异常</p>
<p>存在问题：每一个 <code>Servlet</code> 中都有类似的反射技术的代码，冗余度高</p>
</li>
<li><p>解决方法：提取公共部分，设计了中央控制器类：<code>DispatcherServlet</code>。这个类的工作分为两大部分：</p>
<ul>
<li><p>根据url定位到能够处理这个请求的 <code>Controller</code> 组件</p>
<ul>
<li>从 url 中提取 <code>servletPath : /fruit.do</code></li>
<li>根据 fruit 找到对应的组件: <code>FruitController</code> （其对应关系保存在 XML 文件中，通过 DOM 技术解析 XML 文件，在中央控制器中形成一个 <code>beanMap</code> 容器，用来存放所有的 <code>Controller</code> 组件）</li>
<li>根据获取到的 <code>operate</code> 的值定位到 <code>FruitController</code> 中需要调用的方法</li>
</ul>
</li>
<li><p>调用 <code>Controller</code> 组件中的方法</p>
<ul>
<li><p>获取参数</p>
<ul>
<li>获取即将要调用的方法的参数签名信息: <code>method.getParameters()</code></li>
<li>通过 <code>parameter.getName()</code> 获取参数的名称；</li>
<li>用 <code>Object[] parameterValues</code> 数组存放对应参数的参数值</li>
<li>另外需要考虑参数的类型问题：做类型转化的工作。通过 <code>parameter.getType()</code> 获取参数的类型</li>
</ul>
</li>
<li><p>执行方法：</p>
<p><code>Object returnObj = method.invoke(controllerBean , parameterValues);</code></p>
</li>
<li><p>视图处理</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="type">String</span> <span class="variable">returnStr</span> <span class="operator">=</span> (String)returnObj;</span><br><span class="line"><span class="keyword">if</span>(returnStr.startWith(<span class="string">&quot;redirect:&quot;</span>)) &#123;</span><br><span class="line">    ...</span><br><span class="line">&#125; <span class="keyword">else</span> <span class="keyword">if</span>...</span><br></pre></td></tr></table></figure></li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><p>Servlet中的初始化方法有两个：<code>init()</code> , <code>init(config)</code><strong>（课时46）</strong></p>
<p>如想要在 <code>Servlet</code> 初始化时做一些准备工作，可以重写init方法</p>
<p>可以通过如下步骤去获取初始化设置的数据</p>
<ul>
<li>获取 config 对象：<code>ServletConfig config = getServletConfig();</code></li>
<li>获取初始化参数值： <code>config.getInitParameter(key);</code></li>
</ul>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">init</span><span class="params">()</span> <span class="keyword">throws</span> ServletException&#123;</span><br><span class="line">    </span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">init</span><span class="params">(ServletConfig config)</span> <span class="keyword">throws</span> ServletException &#123;</span><br><span class="line">    <span class="built_in">this</span>.config = config ;</span><br><span class="line">    init();</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>两种方式配置 <code>Servlet</code><strong>（课时46）</strong></p>
<ul>
<li><p>在 <code>web.xml</code> 中配置</p>
<figure class="highlight xml"><table><tr><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">servlet</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">servlet-name</span>&gt;</span>Demo01Servlet<span class="tag">&lt;/<span class="name">servlet-name</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">servlet-class</span>&gt;</span>com.atguigu.servlet.Demo01Servlet<span class="tag">&lt;/<span class="name">servlet-class</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">init-param</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">param-name</span>&gt;</span>hello<span class="tag">&lt;/<span class="name">param-name</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">param-value</span>&gt;</span>world<span class="tag">&lt;/<span class="name">param-value</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">init-param</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">init-param</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">param-name</span>&gt;</span>uname<span class="tag">&lt;/<span class="name">param-name</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">param-value</span>&gt;</span>jim<span class="tag">&lt;/<span class="name">param-value</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">init-param</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">servlet</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">servlet-mapping</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">servlet-name</span>&gt;</span>Demo01Servlet<span class="tag">&lt;/<span class="name">servlet-name</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">url-pattern</span>&gt;</span>/demo01<span class="tag">&lt;/<span class="name">url-pattern</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">servlet-mapping</span>&gt;</span></span><br></pre></td></tr></table></figure>
</li>
<li><p>通过注解配置</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="meta">@WebServlet(urlPatterns = &#123;&quot;/demo01&quot;&#125; ,</span></span><br><span class="line"><span class="meta">     initParams = &#123;</span></span><br><span class="line"><span class="meta">         @WebInitParam(name=&quot;hello&quot;,value=&quot;world&quot;),</span></span><br><span class="line"><span class="meta">         @WebInitParam(name=&quot;uname&quot;,value=&quot;jim&quot;)</span></span><br><span class="line"><span class="meta">     &#125;)</span></span><br></pre></td></tr></table></figure></li>
</ul>
</li>
<li><p>Servlet 中的 <code>ServletContext</code> 和 <code>&lt;context-param&gt;</code><strong>（课时46）</strong></p>
<ul>
<li><p>获取  <code>ServletContext</code> </p>
<ul>
<li>在初始化方法中： <code>ServletContxt servletContext = getServletContext();</code></li>
<li>在服务方法中也可以通过 request 对象获取，也可以通过 session 获取：<code>request.getServletContext(); session.getServletContext()</code></li>
</ul>
</li>
<li><p>获取初始化值：<code>servletContext.getInitParameter();</code></p>
</li>
</ul>
</li>
<li><p>MVC：<code>Model（模型）、View（视图）、Controller（控制器）</code><strong>（课时47）</strong></p>
<ul>
<li><p>视图层：用于做数据展示以及和用户交互的一个界面</p>
</li>
<li><p>控制层：能够接受客户端的请求，具体的业务功能还是需要借助于模型组件来完成</p>
</li>
<li><p>模型层：模型分为很多种：有比较简单的pojo&#x2F;vo(value object)，有业务模型组件，有数据访问层组件</p>
<ul>
<li>pojo &#x2F; vo：值对象</li>
<li>DAO：数据访问对象</li>
<li>BO：业务对象</li>
</ul>
</li>
<li><p>区分 BO(业务对象) 和 DAO(数据访问对象)：</p>
<ul>
<li><p>DAO 中的方法都是 <code>单精度方法/细粒度方法</code>：一个方法只考虑一个操作</p>
<ul>
<li>如添加即 (insert) 操作、查询即 (select) 操作….</li>
</ul>
</li>
<li><p>BO 中的方法属于业务方法，如完成注册业务需如下步骤：</p>
<ul>
<li>检查用户名是否已经被注册 - DAO中的select操作</li>
<li>向用户表新增一条新用户记录 - DAO中的insert操作</li>
<li>向用户积分表新增一条记录（新用户默认初始化积分100分） - DAO中的insert操作</li>
<li>向系统消息表新增一条记录（新用户注册后，根据通讯录信息向他的联系人推送消息） - DAO中的insert操作</li>
<li>向系统日志表新增一条记录（xx用户在xxIP在x年x月x日x时x分x秒x毫秒注册） - DAO中的insert操作</li>
<li>。。。</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><p>IOC 容器<strong>（课时48）</strong>：降低耦合度</p>
<ul>
<li><p>耦合 &#x2F; 依赖</p>
<ul>
<li>在软件系统中，层与层之间是存在依赖的，也称之为耦合</li>
<li>系统架构或者是设计的一个原则是： <strong>高内聚低耦合</strong>，最理想的情况 0 耦合（即没有耦合）</li>
</ul>
</li>
<li><p>IOC - 控制反转（Inversion of Control）</p>
<ul>
<li><p>问题：在 Servlet 中创建了 service 对象 <code>FruitService fruitService = new FruitServiceImpl();</code></p>
<p>根据创建对象的位置（方法内部 &#x2F; 成员变量）可得该对象有不同的生命周期</p>
</li>
<li><p>改进：在 <code>applicationContext.xml</code> 中定义了 <code>fruitService</code>。然后通过解析 XML，产生<code>fruitService</code> 实例，存放在 <code>beanMap</code> 中（<code>beanMap</code> 在一个 <code>BeanFactory</code> 中）</p>
</li>
<li><p>因此转移（改变）了之前的 service 实例、dao 实例等等的生命周期。控制权从程序员转移到BeanFactory。这个现象即控制反转</p>
</li>
</ul>
</li>
<li><p>DI - 依赖注入（Dependency Injection）</p>
<ul>
<li><p>问题：在控制层创建对象：<code>FruitService fruitService = new FruitServiceImpl()；</code></p>
<p>控制层和 <code>service</code> 层存在耦合</p>
</li>
<li><p>改进：将代码修改成 <code>FruitService fruitService = null;</code></p>
<p>然后，在配置文件中配置：</p>
<figure class="highlight xml"><table><tr><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;fruit&quot;</span> <span class="attr">class</span>=<span class="string">&quot;FruitController&quot;</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;fruitService&quot;</span> <span class="attr">ref</span>=<span class="string">&quot;fruitService&quot;</span>/&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br></pre></td></tr></table></figure></li>
</ul>
</li>
</ul>
</li>
<li><p>过滤器（课时50）</p>
<ul>
<li><p>Filter 也属于 Servlet 规范</p>
</li>
<li><p>Filter开发步骤：</p>
<ul>
<li>新建类实现 Filter 接口，然后实现其中的三个方法：<code>init、doFilter、destroy</code></li>
<li>配置 Filter，可以用注解 <code>@WebFilter</code>，也可以使用 xml 文件 <code>&lt;filter&gt; &lt;filter-mapping&gt;</code></li>
</ul>
</li>
<li><p>Filter 在配置时，和 servlet 一样，也可以配置通配符，例如 <code>@WebFilter(&quot;*.do&quot;)</code> 表示拦截所有以.do结尾的请求</p>
</li>
<li><p>过滤器链</p>
<ul>
<li>执行的顺序依次是： A B C demo01 C2 B2 A2</li>
<li>如果采取的是注解的方式进行配置，那么过滤器链的拦截顺序是按照 <code>全类名的先后顺序</code> 排序的</li>
<li>如果采取的是 xml 的方式进行配置，那么按照配置的先后顺序进行排序</li>
</ul>
</li>
</ul>
</li>
<li><p>事务管理（课时51-53）</p>
<ul>
<li><p>步骤（看课）：</p>
<ul>
<li>关闭自动提交</li>
<li>开启事务</li>
<li>操作。。。</li>
<li>操作成功-提交事务；操作失败-回滚事务</li>
</ul>
</li>
<li><p>ThreadLocal：ThreadLocal 称之为本地线程 。 可以通过 set 方法在当前线程上存储数据、通过 get 方法在当前线程上获取数据</p>
</li>
</ul>
</li>
<li><p>监听器（课时54）</p>
<ul>
<li><p>常用监听器</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">// 1.监听 ServletContext 对象的创建和销毁的过程</span></span><br><span class="line">ServletContextListener</span><br><span class="line"><span class="comment">// 2.监听 HttpSession 对象的创建和销毁的过程</span></span><br><span class="line">HttpSessionListener</span><br><span class="line"><span class="comment">// 3.监听 ServletRequest 对象的创建和销毁的过程</span></span><br><span class="line">ServletRequestListener</span><br><span class="line"></span><br><span class="line"><span class="comment">// 4.监听 ServletContext 的保存作用域的改动 (add,remove,replace)</span></span><br><span class="line">ServletContextAttributeListener</span><br><span class="line"><span class="comment">// 5.监听 HttpSession 的保存作用域的改动 (add,remove,replace)</span></span><br><span class="line">HttpSessionAttributeListener</span><br><span class="line"><span class="comment">// 6.监听 ServletRequest 的保存作用域的改动 (add,remove,replace)</span></span><br><span class="line">ServletRequestAttributeListener</span><br><span class="line"></span><br><span class="line"><span class="comment">// 7.监听某个对象在 Session 域中的创建与移除</span></span><br><span class="line">HttpSessionBindingListener</span><br><span class="line"><span class="comment">// 8.监听某个对象在 Session 域中的序列化和反序列化</span></span><br><span class="line">HttpSessionActivationListener</span><br></pre></td></tr></table></figure>
</li>
<li><p>监听器应用：在创建xx时自动创建需要用到的控件，加快响应速度</p>
</li>
</ul>
</li>
</ul>
<h3 id="QQZone-项目实战"><a href="#QQZone-项目实战" class="headerlink" title="QQZone 项目实战"></a>QQZone 项目实战</h3><ul>
<li><p>业务分析</p>
<ul>
<li><p>主要业务</p>
<ul>
<li><p>用户登录</p>
</li>
<li><p>登录成功，显示主界面。左侧显示好友列表；上端显示欢迎词。如果不是自己的空间，显示超链接：返回自己的空间；下端显示日志列表</p>
</li>
<li><p>查看日志详情：</p>
<ul>
<li>日志本身的信息（作者头像、昵称、日志标题、日志内容、日志的日期）</li>
<li>回复列表（回复者的头像、昵称、回复内容、回复日期）</li>
<li>主人回复信息</li>
</ul>
</li>
<li><p>删除日志</p>
</li>
<li><p>删除特定回复</p>
</li>
<li><p>删除特定主人回复</p>
</li>
<li><p>添加日志、添加回复、添加主人回复</p>
</li>
<li><p>点击左侧好友链接，进入好友的空间</p>
</li>
</ul>
</li>
<li><p>数据库设计</p>
<ul>
<li><p>抽取实体 : </p>
<ul>
<li>用户登录信息</li>
<li>用户详情信息 </li>
<li>日志</li>
<li>回贴</li>
<li>主人回复</li>
</ul>
</li>
<li><p>分析其中的属性：</p>
<ul>
<li>用户登录信息：账号、密码、头像、昵称</li>
<li>用户详情信息：真实姓名、星座、血型、邮箱、手机号…..</li>
<li>日志：标题、内容、日期、作者</li>
<li>回复：内容、日期、作者、日志</li>
<li>主人回复：内容、日期、作者、回复</li>
</ul>
</li>
<li><p>分析实体之间的关系：</p>
<ul>
<li>用户登录信息 ： 用户详情信息	   1 : 1 PK</li>
<li>用户 ： 日志						              1 : N</li>
<li>日志 ： 回复                                      1 : N</li>
<li>回复 ： 主人回复                               1 : 1 UK</li>
<li>用户 ： 好友                                      M : N</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><p>数据库范式</p>
<p>需数据库性能平衡。范式节约空间，性能提高效率</p>
<p><strong>查询频次不高则倾向范式；反之倾向性能</strong></p>
<ul>
<li>第一范式（1NF）：列不可再分</li>
<li>第二范式（2NF）：一张表只表达一层含义（只描述一件事情）</li>
<li>第三范式（3NF）：表中每一列和主键都是直接依赖关系，而不是间接依赖</li>
</ul>
</li>
<li><p>部分功能实现</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">1.top.html 页面显示登录者昵称、判断是否是自己的空间</span><br><span class="line">   1) 显示登录者昵称： $&#123;session.userBasic.nickName&#125;</span><br><span class="line">   2) 判断是否是自己的空间 : $&#123;session.userBasic.id!=session.friend.id&#125; 如果不是期望的效果，首先考虑将两者的id都显示出来</span><br><span class="line"></span><br><span class="line">2.点击左侧的好友链接，进入好友空间</span><br><span class="line">   1) 根据 id 获取指定 userBasic 信息，查询这个 userBasic 的 topicList，然后覆盖 friend 对应的 value</span><br><span class="line">   2) main 页面应该展示 friend 中的 topicList，而不是 userBasic 中的 topicList</span><br><span class="line">   3) 跳转后，在左侧（left）中显示整个 index 页面</span><br><span class="line">      - 问题：在 left 页面显示整个 index 布局</span><br><span class="line">      - 解决：给超链接添加 target 属性: target=&quot;_top&quot; 保证在顶层窗口显示整个 index 页面</span><br><span class="line">   4) top.html 页面需要修改: &quot;欢迎进入$&#123;session.friend&#125;&quot;</span><br><span class="line">      top.html 页面的返回自己空间的超链接需要修改: </span><br><span class="line">      &lt;a th:href=&quot;@&#123;|/user.do?operate=friend&amp;id=$&#123;session.userBasic.id&#125;|&#125;&quot; target=&quot;_top&quot;&gt;</span><br><span class="line"></span><br><span class="line">3.日志详情页面实现</span><br><span class="line">   1) 已知 topic 的 id，需要根据 topic 的 id 获取特定 topic</span><br><span class="line">   2) 获取这个 topic 关联的所有的回复</span><br><span class="line">   3) 如果某个回复有主人回复，需要查询出来</span><br><span class="line">   	  - 在 TopicController 中获取指定的 topic</span><br><span class="line">   	  - 具体这个 topic 中关联多少个 Reply，由 ReplyService 内部实现</span><br><span class="line">   4) 获取到的 topic 中的 author 只有 id，那么需要在 topicService 的 getTopic 方法中封装，在查询 topic 本身信息时，同时调用 userBasicService 中的获取 userBasic 方法，给 author 属性赋值</span><br><span class="line">   5) 同理，在 reply 类中也有 author，而且这个 author 也是只有 id，那么我们也需要根据 id 查询得到 author，最后设置关联</span><br><span class="line"></span><br><span class="line">4.添加回复</span><br><span class="line"></span><br><span class="line">5.删除回复</span><br><span class="line">   1) 如果回复有关联的主人回复，需要先删除主人回复</span><br><span class="line">   2) 删除回复</span><br><span class="line">   Cannot delete or update a parent row: a foreign key constraint fails</span><br><span class="line">   (`qqzonedb`.`t_host_reply`, CONSTRAINT `FK_host_reply` FOREIGN KEY (`reply`) REFERENCES `t_reply` (`id`))</span><br><span class="line">    我们在删除回复表记录时，发现删除失败，原因是：在主人回复表中仍然有记录引用待删除的回复这条记录。如果需要删除主表数据，需要首先删除子表数据</span><br><span class="line">    </span><br><span class="line">6.删除日志</span><br><span class="line">   1) 删除日志，首先需要考虑是否有关联的回复</span><br><span class="line">   2) 删除回复，首先需要考虑是否有关联的主人回复</span><br><span class="line">   3) 另外，如果不是自己的空间，则不能删除日志</span><br></pre></td></tr></table></figure>
</li>
<li><p>细节</p>
<ul>
<li><p>系统启动时，我们访问的页面是：<code>http://localhost:8080/pro23/page.do?operate=page&amp;page=login</code>  为什么不是：<code>http://localhost:8080/pro23/login.html</code>  </p>
<p>答：如果是后者，那么属于直接访问静态页面。那么页面上的 <code>thymeleaf表达式（标签）</code> 浏览器是不能识别的。访问前者的目的其实就是要执行 <code>ViewBaseServlet</code> 中的<code>processTemplete()</code></p>
</li>
<li><p><code>http://localhost:8080/qqzone/page.do?operate=page&amp;page=login</code> 访问这个URL，执行的过程是什么样的</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">各部分含义如下: </span><br><span class="line">http://							协议</span><br><span class="line">localhost   					ServerIP</span><br><span class="line">:8080   						端口</span><br><span class="line">/qqzone          				项目名称</span><br><span class="line">/page.do                    	request.getServletPath()</span><br><span class="line">?operate=page&amp;page=login		query string</span><br></pre></td></tr></table></figure>

<ul>
<li><p><code>DispatcherServlet -&gt; urlPattern</code> :  *.do  拦截&#x2F;page.do</p>
</li>
<li><p><code>request.getServletPath() -&gt;  /page.do</code></p>
</li>
<li><p>解析处理字符串，将 <code>/page.do -&gt; page</code></p>
</li>
<li><p>获取字符串 <code>page</code>，然后去 IOC容器（BeanFactory）中寻找 <code>id=page</code> 的 bean 对象   -&gt; <code>PageController.java</code></p>
</li>
<li><p>获取 <code>operate = page</code>    因此得知，应该执行 <code>PageController</code> 中的 <code>page() </code>方法</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">// PageController 中的 page 方法定义如下：</span></span><br><span class="line"><span class="keyword">public</span> String <span class="title function_">page</span><span class="params">(String page)</span>&#123;</span><br><span class="line">    <span class="keyword">return</span> page ;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>在 queryString <code>?operate=page&amp;page=login</code> 中获取请求参数，参数名是 page，参数值是 login：因此 page 方法的参数 page 值会被赋上 <code>login</code>，然后 return</p>
</li>
<li><p>因为 <code>PageController</code> 的 <code>page</code> 方法是 <code>DispatcherServlet</code> 通过反射调用的 <code>method.invoke(....) ;</code>，因此，字符串 <code>login</code> 返回给 <code>DispatcherServlet</code></p>
</li>
<li><p>DispatcherServlet接收到返回值，然后处理视图。目前处理视图的方式有两种： </p>
<ul>
<li>带前缀 <code>redirect:</code></li>
<li>不带前缀</li>
</ul>
<p><code>login</code> 不带前缀，执行 <code>super.processTemplete(&quot;login&quot;,request,response);</code></p>
</li>
<li><p>此时 <code>ViewBaseServlet</code> 中的 <code>processTemplete</code> 方法会执行，效果是：</p>
<ul>
<li>在 <code>login</code> 这个字符串前面拼接 <code>/</code>  (即配置文件中 <code>view-prefixe</code> 配置的值)</li>
<li>在 <code>login</code> 这个字符串后面拼接 <code>.html</code> (即配置文件中 <code>view-suffix</code> 配置的值)</li>
</ul>
<p>最后进行服务器转发</p>
</li>
</ul>
</li>
</ul>
</li>
<li><p><strong>Java WEB 项目开发流程</strong></p>
<ol>
<li><p>拷贝 <code>myssm</code> 包：基础工具包</p>
</li>
<li><p>新建配置文件 <code>applicationContext.xml</code> 或者可以不叫这个名字，在 <code>web.xml</code> 中指定文件名</p>
</li>
<li><p>在 <code>web.xml</code> 文件中配置：</p>
<ul>
<li><p>配置前缀和后缀，这样 <code>thymeleaf</code> 引擎就可以根据我们返回的字符串进行拼接，再跳转</p>
<figure class="highlight xml"><table><tr><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">context-param</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">param-name</span>&gt;</span>view-prefix<span class="tag">&lt;/<span class="name">param-name</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">param-value</span>&gt;</span>/<span class="tag">&lt;/<span class="name">param-value</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">context-param</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">context-param</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">param-name</span>&gt;</span>view-suffix<span class="tag">&lt;/<span class="name">param-name</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">param-value</span>&gt;</span>.html<span class="tag">&lt;/<span class="name">param-value</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">context-param</span>&gt;</span></span><br></pre></td></tr></table></figure>
</li>
<li><p>配置监听器要读取的参数，目的是加载IOC容器的配置文件（也就是<code>applicationContext.xml</code>）</p>
<figure class="highlight xml"><table><tr><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">context-param</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">param-name</span>&gt;</span>contextConfigLocation<span class="tag">&lt;/<span class="name">param-name</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">param-value</span>&gt;</span>applicationContext.xml<span class="tag">&lt;/<span class="name">param-value</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">context-param</span>&gt;</span></span><br></pre></td></tr></table></figure></li>
</ul>
</li>
<li><p>开发具体的业务模块：</p>
<ul>
<li><p>一个具体的业务模块纵向上由几个部分组成：</p>
</li>
<li><p>如果 <code>html</code> 页面有 <code>thymeleaf</code> 表达式，一定不能够直接访问，必须要经过 <code>PageController</code></p>
</li>
<li><p>在 <code>applicationContext.xml</code> 中配置 <code>DAO、Service、Controller</code>，以及三者之间的依赖关系</p>
</li>
<li><p>DAO 实现类中，继承 <code>myssm/BaseDAO</code>，然后实现具体的接口, 需要注意，BaseDAO后面的泛型不能写错</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">UserDAOImpl</span> <span class="keyword">extends</span> <span class="title class_">BaseDAO</span>&lt;User&gt; <span class="keyword">implements</span> <span class="title class_">UserDAO</span>&#123;&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>Service 是业务控制类：</p>
<ul>
<li>业务逻辑我们都封装在 <code>service</code> 这一层，不要分散在 <code>Controller</code> 层。也不要出现在 DAO层（我们需要保证 DAO方法的单精度特性）</li>
<li>当某一个业务功能需要使用其他模块的业务功能时，尽量的调用别人的 <code>service</code>，而不是深入到其他模块的 DAO 细节</li>
</ul>
</li>
<li><p>Controller 类的编写规则：</p>
<ul>
<li><p>在 <code>applicationContext.xml</code> 中配置 <code>Controller</code></p>
<figure class="highlight xml"><table><tr><td class="code"><pre><span class="line">用户在前端发请求时，对应的servletpath就是/user.do, 其中的“user”就是对应此处的bean的id值    </span><br><span class="line"><span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;user&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.atguigu.qqzone.controllers.UserController&gt;</span></span></span><br></pre></td></tr></table></figure>
</li>
<li><p>在 <code>Controller</code> 中设计的方法名需要和 <code>operate</code> 的值一致</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">public String login(String loginId , String pwd , HttpSession session)&#123;</span><br><span class="line">	return &quot;index&quot;;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">因此，我们的登录验证的表单如下：</span><br><span class="line">&lt;form th:action=&quot;@&#123;/user.do&#125;&quot; method=&quot;post&quot;&gt;</span><br><span class="line">	&lt;inut type=&quot;hidden&quot; name=&quot;operate&quot; value=&quot;login&quot;/&gt;</span><br><span class="line">&lt;/form&gt;</span><br></pre></td></tr></table></figure>
</li>
<li><p>在表单中，组件的 name 属性和 Controller 中方法的参数名一致</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">&lt;input type=&quot;text&quot; name=&quot;loginId&quot; /&gt;</span><br><span class="line">public String login(String loginId , String pwd , HttpSession session);</span><br></pre></td></tr></table></figure>
</li>
<li><p>Controller中的方法中的参数不一定都是通过请求参数获取的</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">if(&quot;request&quot;.equals...) &#123;</span><br><span class="line">	直接赋值</span><br><span class="line">&#125; else if(&quot;response&quot;.equals....)&#123;</span><br><span class="line">	直接赋值</span><br><span class="line">&#125; else if(&quot;session&quot;.equals....)&#123;</span><br><span class="line">	直接赋值</span><br><span class="line">&#125; else &#123;</span><br><span class="line">    此处才是从request的请求参数中获取</span><br><span class="line">    request.getParameter(&quot;loginId&quot;) .....</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
<li><p><code>DispatcherServlet</code> 中步骤大致分为：</p>
<ol>
<li>从 <code>application</code> 作用域获取IOC容器</li>
<li>解析 <code>servletPath</code> ， 在IOC容器中寻找对应的 <code>Controller</code> 组件</li>
<li>准备 <code>operate</code> 指定的方法所要求的参数</li>
<li>调用 <code>operate</code> 指定的方法</li>
<li>接收到执行 <code>operate</code> 指定的方法的返回值，对返回值进行处理 - 视图处理</li>
</ol>
</li>
<li><p>为什么 <code>DispatcherServlet</code> 能够从 <code>application</code> 作用域获取到 IOC容器？</p>
<p><code>ContextLoaderListener</code> 在容器启动时会执行初始化任务，而它的操作就是：</p>
<ul>
<li>解析 IOC 的配置文件，创建一个一个的组件，并完成组件之间依赖关系的注入</li>
<li>将 IOC 容器保存到 <code>application</code> 作用域</li>
</ul>
</li>
<li><p>简化 BaseDAO，有以下两种方式：</p>
<ul>
<li>直接自己配置 <code>properties</code>，然后读取，然后加载驱动…..</li>
<li>使用 <code>druid</code>连接池技术，那么 <code>properties</code> 中的 <code>key</code> 是有要求的</li>
</ul>
</li>
<li><p><a target="_blank" rel="noopener" href="https://blog.csdn.net/zhyhang/article/details/89060408">通用代码 <code>myssm文件夹</code> 导出为 jar 包</a></p>
</li>
</ul>
<h3 id="图书商城项目"><a href="#图书商城项目" class="headerlink" title="图书商城项目"></a>图书商城项目</h3><ul>
<li><p>数据库设计</p>
<ul>
<li>实体分析<ul>
<li>图书                Book</li>
<li>用户                User</li>
<li>订单                OrderBean</li>
<li>订单详情         OrderItem</li>
<li>购物车项         CartItem</li>
</ul>
</li>
<li>实体属性分析<ul>
<li>图书 : 书名、作者、价格、销量、库存、封面、状态</li>
<li>用户 : 用户名、密码、邮箱、角色（管理员、普通用户）</li>
<li>订单 : 订单编号、订单日期、订单金额、订单数量、订单状态、用户</li>
<li>订单详情 : 图书、数量、所属订单</li>
<li>购物车项 : 图书、数量、所属用户</li>
</ul>
</li>
<li>分析实体之间的关系<ul>
<li>用户 ：购物车项	     1 : N</li>
<li>用户 ：订单				 1 : N</li>
<li>订单 ：订单详情         1 : N</li>
<li>图书 ：订单详情         1 : N</li>
<li>图书 ：购物车项：     1 : N</li>
</ul>
</li>
</ul>
</li>
<li><p><strong>Cookie（服务器缓存）</strong></p>
<ul>
<li><p>使用步骤：</p>
<ul>
<li><p>创建 Cookie 对象</p>
</li>
<li><p>在客户端保存 Cookie</p>
</li>
<li><p>设置Cookie的有效时长</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">// setMaxAge 以秒为单位</span></span><br><span class="line"><span class="comment">// 设置 cookie 的有效时长是 60 秒</span></span><br><span class="line">cookie.setMaxAge(<span class="number">60</span>);</span><br><span class="line"><span class="comment">// 一般情况下，以下两个不设置</span></span><br><span class="line">cookie.setDomain(pattern);</span><br><span class="line">cookie.setPath(uri);</span><br></pre></td></tr></table></figure></li>
</ul>
</li>
<li><p>应用场景：</p>
<ul>
<li>记住用户名和密码十天 <code>setMaxAge(60 * 60 * 24 * 10)</code></li>
<li>十天免登录</li>
</ul>
</li>
</ul>
</li>
<li><p><strong>Kaptcha（验证码）</strong></p>
<ul>
<li><p>为什么需要验证码：防止爬虫恶意请求</p>
</li>
<li><p>kaptcha 如何使用：</p>
<ol>
<li><p>添加 jar</p>
</li>
<li><p>在 <code>web.xml</code> 文件中注册 <code>KaptchaServlet</code>，并设置验证码图片的相关属性</p>
</li>
<li><p>在 <code>html</code> 页面上编写一个 <code>img</code> 标签，然后设置 <code>src</code> 等于 <code>KaptchaServlet</code> 对应的 <code>url-pattern</code></p>
</li>
</ol>
</li>
<li><p><code>kaptcha</code> 验证码图片的各个属性在常量接口：<code>Constants</code> 中</p>
</li>
<li><p><code>KaptchaServlet</code> 在生成验证码图片时，会同时将验证码信息保存到 <code>session</code> 中</p>
<p>因此在注册请求时，首先将用户文本框中输入的验证码值和 <code>session</code> 中保存的值进行比较，相等则进行注册</p>
</li>
</ul>
</li>
<li><p><strong>JS - Exp（正则表达式）</strong></p>
<ul>
<li><p>正则表达式的使用三步骤：</p>
<ol>
<li><p>定义正则表达式对象</p>
<ul>
<li><p>正则表达式定义有两个方式：</p>
<ul>
<li>对象形式：<code>var reg = new RegExp(&quot;abc&quot;)</code></li>
<li>直接量形式：<code>var reg = /abc/;</code></li>
</ul>
</li>
<li><p>匹配模式：</p>
<ul>
<li><p>g 全局匹配</p>
</li>
<li><p>i 忽略大小写匹配</p>
</li>
<li><p>m 多行匹配</p>
</li>
<li><p><code>gim</code> 这三个可以组合使用，不区分先后顺序。如：</p>
<p><code>var reg = /abc/gim;</code> </p>
<p><code>var reg = new RegExp(&quot;abc&quot;,&quot;gim&quot;);</code></p>
</li>
</ul>
</li>
</ul>
</li>
<li><p>定义待校验的字符串</p>
</li>
<li><p>校验</p>
</li>
</ol>
</li>
<li><p>元字符：<code>. , \w , \W , \s , \S , \d , \D , \b , ^ , $</code></p>
</li>
<li><p><code>[]</code> 表集合</p>
<ul>
<li><code>[abc]</code> 表示 a 或者 b 或者 c</li>
<li><code>[^abc]</code> 表示取反，只要不是 a 不是 b 不是 c 就匹配</li>
<li><code>[a-c]</code> 表示 a 到 c 这个范围匹配</li>
</ul>
</li>
<li><p>出现次数</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">* 		表示多次 （<span class="number">0</span> ~ n ）</span><br><span class="line">+ 		至少一次 ( &gt;=<span class="number">1</span> )</span><br><span class="line">? 		最多一次 (<span class="number">0</span> ~ <span class="number">1</span>)</span><br><span class="line">&#123;n&#125; 	出现n次</span><br><span class="line">&#123;n,&#125; 	出现n次或者多次</span><br><span class="line">&#123;n,m&#125; 	出现n到m次</span><br></pre></td></tr></table></figure></li>
</ul>
</li>
<li><p><strong><a target="_blank" rel="noopener" href="https://www.runoob.com/ajax/ajax-tutorial.html">原生 AJAX</a></strong> ：Asynchronous JavaScript and XML（异步的 JavaScript 和 XML）</p>
<ul>
<li><p>AJAX 不是新的编程语言，而是一种使用现有标准的新方法</p>
</li>
<li><p>AJAX 目的： 用来发送异步的请求，然后当服务器给我响应的时候再进行回调操作</p>
</li>
<li><p>AJAX 最大的优点是在不重新加载整个页面的情况下，可以与服务器交换数据并更新部分网页内容</p>
<p>提高用户体验；<strong>局部刷新</strong>：降低服务器负担、减轻浏览器压力、减轻网络带宽压力</p>
</li>
<li><p>AJAX 不需要任何浏览器插件，但需要用户允许 JavaScript 在浏览器上执行</p>
</li>
<li><p>开发步骤</p>
<ol>
<li><p>客户端发送异步请求；并绑定对结果处理的回调函数</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">1. &lt;input type=&quot;text&quot; name=&quot;uname&quot; onblur=&quot;ckUname()&quot;/&gt;</span><br><span class="line"></span><br><span class="line">2. 定义 ckUname 方法：</span><br><span class="line">    - 创建 XMLHttpRequest 对象</span><br><span class="line">    - XMLHttpRequest 对象操作步骤：</span><br><span class="line">    - open(&quot;GET&quot;, url, true)</span><br><span class="line">    - onreadyStateChange 设置回调</span><br><span class="line">    - send() 发送请求</span><br><span class="line">    - 在回调函数中需要判断 XMLHttpRequest 对象的状态: readyState(0-4) , status(200)</span><br></pre></td></tr></table></figure>

<p><code>readyState</code> 状态码（0~4）</p>
<ul>
<li>0 －（未初始化）还没有调用 send() 方法</li>
<li>1 －（载入）已调用 send() 方法，正在发送请求</li>
<li>2 －（载入完成）send() 方法执行完成，已经接收到全部响应内容</li>
<li>3 －（交互）正在解析响应内容</li>
<li><strong>4 －（完成）响应内容解析完成，可以在客户端调用了</strong></li>
</ul>
</li>
<li><p>服务器端做校验，然后将校验结果响应给客户端</p>
</li>
</ol>
</li>
</ul>
</li>
<li><p><a target="_blank" rel="noopener" href="https://www.runoob.com/vue2/vue-tutorial.html">Vue</a>：是一套构建用户界面的渐进式框架</p>
<ul>
<li>Vue 只关注视图层， 采用自底向上增量开发的设计</li>
<li>Vue 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件</li>
<li>常用用法<ul>
<li><code>&#123;&#123;&#125;&#125;</code>：相当于 innerText</li>
<li><code>v-bind:attr</code> 绑定属性值。如 <code>v-bind:value</code>：绑定 value 值（简写<code>:value</code>）</li>
<li><code>v-model</code> 双向绑定。<code>v-model:value</code> ，简写  <code>v-model</code></li>
<li><code>v-if , v-else , v-show</code><br><code>v-if</code> 和 <code>v-else</code> 之间不能有其他的节点<br><code>v-show</code> 是通过样式表 <code>display</code> 来控制节点是否显示</li>
<li><code>v-for</code> 迭代。如<code>v-for=&#123;fruit in fruitList&#125;</code></li>
<li><code>v-on</code> 绑定事件</li>
<li><code>trim</code>：去除首尾空格 , <code>split() , join()</code></li>
<li><code>watch</code> 表示侦听属性</li>
<li><a target="_blank" rel="noopener" href="https://www.jianshu.com/p/672e967e201c">Vue 对象生命周期</a></li>
</ul>
</li>
</ul>
</li>
<li><p><a target="_blank" rel="noopener" href="https://www.runoob.com/vue2/vuejs-ajax-axios.html">Axios</a>：Axios 是 Ajax 的一个框架，简化 Ajax 操作</p>
<ul>
<li><p>Axios 执行 Ajax 操作的步骤：</p>
<ol>
<li><p>添加并引入 axios 的 js 文件</p>
</li>
<li><p>客户端向服务器端异步发送请求</p>
<ul>
<li><p>客户端向服务器端异步发送普通参数值</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">axios(&#123;</span><br><span class="line">    method:&quot;POST&quot;,</span><br><span class="line">    url:&quot;....&quot;,</span><br><span class="line">    params:&#123;</span><br><span class="line">        uname:&quot;lina&quot;,</span><br><span class="line">        pwd:&quot;ok&quot;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;)</span><br><span class="line">.then(function(value)&#123;&#125;)          </span><br><span class="line">.catch(function(reason)&#123;&#125;);</span><br><span class="line"></span><br><span class="line">// then 表示成功响应时执行的回调：value.data可以获取到服务器响应内容</span><br><span class="line">// catch 表示有异常时执行的回调：reason.response.data可以获取到响应的内容reason.message/reason.stack 可以查看错误的信息</span><br></pre></td></tr></table></figure>
</li>
<li><p>客户端向服务器发送 JSON 格式的数据</p>
<ol>
<li><p>客户端中 <code>params:</code> 需要修改成  <code>data:</code></p>
</li>
<li><p>服务器获取参数值不再是 <code>request.getParameter()...</code>，而是如下：</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="type">StringBuffer</span> <span class="variable">stringBuffer</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">StringBuffer</span>(<span class="string">&quot;&quot;</span>);</span><br><span class="line"><span class="type">BufferedReader</span> <span class="variable">bufferedReader</span> <span class="operator">=</span> request.getReader();</span><br><span class="line"><span class="type">String</span> <span class="variable">str</span> <span class="operator">=</span> <span class="literal">null</span>;</span><br><span class="line"><span class="keyword">while</span>((str = bufferedReader.readLine()) != <span class="literal">null</span>) &#123;</span><br><span class="line">	stringBuffer.append(str);</span><br><span class="line">&#125;</span><br><span class="line">str = stringBuffer.toString();</span><br><span class="line"><span class="comment">// 已知 String，需转为 java 对象</span></span><br><span class="line"><span class="type">Gson</span> <span class="variable">gson</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Gson</span>();</span><br><span class="line"><span class="comment">// 借助 Gson，将 str 转为 User 对象</span></span><br><span class="line"><span class="type">User</span> <span class="variable">user</span> <span class="operator">=</span> gson.fromJson(str, User.class)</span><br></pre></td></tr></table></figure>
</li>
<li><p>str 的内容如： <code>&#123;&quot;uname&quot;:&quot;lina&quot;,&quot;pwd&quot;:&quot;ok&quot;&#125;</code></p>
</li>
</ol>
</li>
</ul>
</li>
<li><p>服务器端给客户端响应 <code>JSON</code> 格式的字符串，然后客户端需要将字符串转化成 <code>js Object</code></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="type">Gson</span> <span class="variable">gson</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Gson</span>();</span><br><span class="line"><span class="type">String</span> <span class="variable">userJsonStr</span> <span class="operator">=</span> gson.toJson(user);</span><br></pre></td></tr></table></figure></li>
</ol>
</li>
</ul>
</li>
<li><p><a target="_blank" rel="noopener" href="https://www.runoob.com/json/json-tutorial.html">JSON</a> 与 XML 对比</p>
<ul>
<li><p>JSON: <strong>J</strong>ava<strong>S</strong>cript <strong>O</strong>bject <strong>N</strong>otation(JavaScript 对象表示法)</p>
<p>JSON 是存储和交换文本信息的语法，类似 XML</p>
<p>JSON 比 XML 更小、更快，更易解析</p>
</li>
<li><p>JSON 表达数据更简洁，更能够节约网络带宽</p>
</li>
</ul>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">// XML 格式表示两个学员信息的代码如下：</span></span><br><span class="line">&lt;students&gt;</span><br><span class="line">    &lt;student sid=<span class="string">&quot;s001&quot;</span>&gt;</span><br><span class="line">    &lt;sname&gt;jim&lt;/sname&gt;</span><br><span class="line">    &lt;age&gt;<span class="number">18</span>&lt;/age&gt;</span><br><span class="line">&lt;/student&gt;</span><br><span class="line">&lt;student sid=<span class="string">&quot;s002&quot;</span>&gt;</span><br><span class="line">    &lt;sname&gt;tom&lt;/sname&gt;</span><br><span class="line">    &lt;age&gt;<span class="number">19</span>&lt;/age&gt;</span><br><span class="line">    &lt;/student&gt;</span><br><span class="line">&lt;/students&gt;</span><br><span class="line"></span><br><span class="line"><span class="comment">// JSON格式表示两个学员信息的代码如下：</span></span><br><span class="line">[&#123;sid:<span class="string">&quot;s001&quot;</span>,age:<span class="number">18</span>&#125;,&#123;sid:<span class="string">&quot;s002&quot;</span>,age:<span class="number">19</span>&#125;]</span><br></pre></td></tr></table></figure></li>
</ul>
</article><div class="post-copyright"><div class="post-copyright__author"><span class="post-copyright-meta">文章作者: </span><span class="post-copyright-info"><a href="https://gitee.com/zcmmmm/zcmmmm">zcm</a></span></div><div class="post-copyright__type"><span class="post-copyright-meta">文章链接: </span><span class="post-copyright-info"><a href="https://gitee.com/zcmmmm/zcmmmm/2022/09/23/Java-Web/">https://gitee.com/zcmmmm/zcmmmm/2022/09/23/Java-Web/</a></span></div><div class="post-copyright__notice"><span class="post-copyright-meta">版权声明: </span><span class="post-copyright-info">本博客所有文章除特别声明外，均采用 <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/" target="_blank">CC BY-NC-SA 4.0</a> 许可协议。转载请注明来自 <a href="https://gitee.com/zcmmmm/zcmmmm" target="_blank">无人深空</a>！</span></div></div><div class="tag_share"><div class="post-meta__tag-list"><a class="post-meta__tags" href="/tags/JavaWeb/">JavaWeb</a></div><div class="post_share"><div class="social-share" data-image="https://study-record-images.oss-cn-beijing.aliyuncs.com/Java/JavaWeb/Java%20Web.jpg" data-sites="facebook,twitter,wechat,weibo,qq"></div><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/butterfly-extsrc/sharejs/dist/css/share.min.css" media="print" onload="this.media='all'"><script src="https://cdn.jsdelivr.net/npm/butterfly-extsrc/sharejs/dist/js/social-share.min.js" defer></script></div></div><nav class="pagination-post" id="pagination"><div class="prev-post pull-left"><a href="/2022/09/23/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/"><img class="prev-cover" src="https://study-record-images.oss-cn-beijing.aliyuncs.com/Java/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/Design%20pattern.jpg" onerror="onerror=null;src='/img/404.jpg'" alt="cover of previous post"><div class="pagination-info"><div class="label">上一篇</div><div class="prev_info">设计模式</div></div></a></div><div class="next-post pull-right"><a href="/2022/09/23/%E9%9B%B6%E5%9F%BA%E7%A1%80%E5%AD%A6-Java-03/"><img class="next-cover" src="https://study-record-images.oss-cn-beijing.aliyuncs.com/Java/%E9%9B%B6%E5%9F%BA%E7%A1%80%E5%AD%A6Java/Cover.jpg" onerror="onerror=null;src='/img/404.jpg'" alt="cover of next post"><div class="pagination-info"><div class="label">下一篇</div><div class="next_info">零基础学-Java-03</div></div></a></div></nav></div><div class="aside-content" id="aside-content"><div class="sticky_layout"><div class="card-widget" id="card-toc"><div class="item-headline"><i class="fas fa-stream"></i><span>目录</span><span class="toc-percentage"></span></div><div class="toc-content is-expand"><ol class="toc"><li class="toc-item toc-level-3"><a class="toc-link" href="#2022%E7%89%88JavaWeb%E6%95%99%E7%A8%8B%EF%BC%88%E5%85%A8%E6%96%B0%E6%8A%80%E6%9C%AF%E6%A0%88%EF%BC%8C%E5%85%A8%E7%A8%8B%E5%AE%9E%E6%88%98%EF%BC%89"><span class="toc-text">2022版JavaWeb教程（全新技术栈，全程实战）</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%89%8D%E7%AB%AF%E4%B8%89%E4%BB%B6%E5%A5%97"><span class="toc-text">前端三件套</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#JavaWeb-fruit-%E9%A1%B9%E7%9B%AE"><span class="toc-text">JavaWeb fruit 项目</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#QQZone-%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98"><span class="toc-text">QQZone 项目实战</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%9B%BE%E4%B9%A6%E5%95%86%E5%9F%8E%E9%A1%B9%E7%9B%AE"><span class="toc-text">图书商城项目</span></a></li></ol></div></div></div></div></main><footer id="footer"><div id="footer-wrap"><div class="copyright">&copy;2022 - 2023 By zcm</div><div class="framework-info"><span>框架 </span><a target="_blank" rel="noopener" href="https://hexo.io">Hexo</a><span class="footer-separator">|</span><span>主题 </span><a target="_blank" rel="noopener" href="https://github.com/jerryc127/hexo-theme-butterfly">Butterfly</a></div></div></footer></div><div id="rightside"><div id="rightside-config-hide"><button id="readmode" type="button" title="阅读模式"><i class="fas fa-book-open"></i></button><button id="darkmode" type="button" title="浅色和深色模式转换"><i class="fas fa-adjust"></i></button><button id="hide-aside-btn" type="button" title="单栏和双栏切换"><i class="fas fa-arrows-alt-h"></i></button></div><div id="rightside-config-show"><button id="rightside_config" type="button" title="设置"><i class="fas fa-cog fa-spin"></i></button><button class="close" id="mobile-toc-button" type="button" title="目录"><i class="fas fa-list-ul"></i></button><button id="go-up" type="button" title="回到顶部"><i class="fas fa-arrow-up"></i></button></div></div><div id="local-search"><div class="search-dialog"><nav class="search-nav"><span class="search-dialog-title">搜索</span><span id="loading-status"></span><button class="search-close-button"><i class="fas fa-times"></i></button></nav><div class="is-center" id="loading-database"><i class="fas fa-spinner fa-pulse"></i><span>  数据库加载中</span></div><div class="search-wrap"><div id="local-search-input"><div class="local-search-box"><input class="local-search-box--input" placeholder="搜索文章" type="text"/></div></div><hr/><div id="local-search-results"></div></div></div><div id="search-mask"></div></div><div><script src="/js/utils.js"></script><script src="/js/main.js"></script><script src="https://cdn.jsdelivr.net/npm/@fancyapps/ui/dist/fancybox.umd.min.js"></script><script src="https://cdn.jsdelivr.net/npm/node-snackbar/dist/snackbar.min.js"></script><script src="/js/search/local-search.js"></script><div class="js-pjax"></div><script src="/js/categories.js?v1"></script><script src="/js/navigation.js?v1"></script><script async data-pjax src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script></div></body></html>